/*
 * UMediaReaderSource.h
 *
 *  Created on: 2020年4月25日
 *      Author: chuanjiang.zh
 */

#ifndef UMEDIAREADERSOURCE_H_
#define UMEDIAREADERSOURCE_H_

#include "UMediaSource.h"
#include "UMediaReader.h"
#include "CommandThread.h"
#include <string>
#include <memory>
#include "TimePoint.h"
#include "UMediaSourceT.h"
#include "Ffmpeg.h"


typedef std::shared_ptr<UMediaReader>	UMediaReaderPtr;


class UMediaReaderSource: public UMediaSourceT<UMediaSource>, protected comn::CommandThread
{
public:
	static int STACK_SIZE;
    static bool DEBUG_ENABLED;

    typedef UMediaSourceT<UMediaSource>   BaseMediaSource;

public:
	UMediaReaderSource();
	virtual ~UMediaReaderSource();


	virtual int open(const char* url, const char* params);

	virtual void close();

	virtual bool isOpen();

	virtual bool getMediaFormat(UMediaFormat& fmt);

	virtual int startStream();
	virtual int pauseStream();
	virtual void stopStream();

	virtual bool seekable();

	virtual bool seek(int64_t pos);

	virtual int64_t getTime();

	virtual bool setScale(float scale);

	virtual float getScale();


	virtual int step();
	virtual int nextKeyFrame();



	void setRetryTime(int ms);

	void customAudioTs(bool enabled);

	void setLoopCount(int loopCount);
	bool isLoopEnabled();


protected:
	virtual UMediaReaderPtr createReader(const std::string& url, bool loopEnabled);

protected:
	enum PlayerCommandType
	{
		kOpen = 1,
		kClose,
		kPlay,
		kPause,
		kStop,
		kSeek,
		kFlush,

		kSetScale,
		kStep,
		kNextKeyFrame,

		kSetProp,

		kStartRender,
		kStopRender,
		kSetVideoWindow
	};

	void handleOpen();
	void handleClose();
	void handlePlay();
	void handlePause();
	void handleStop();
	void handleSeek(int64_t offset);
	void handleSetScale(AVRational scale);
	void handleStep();
	void handleNextKeyFrame();

	void handleFlush();
	void handleSetProp(std::string& key, std::string& value);


	void emitMediaEvent(int event);

	void doCloseFile();

	void dispatchPacket(UMediaPacket& pkt);
	int computeDelay(UMediaPacket& pkt);

	int64_t getClock();

	void delay(int ms);

	void resetTimePoint();

	bool readUntilVideoFrame();
	bool readUntilVideoKeyFrame();

	int read(UMediaPacket& pkt);

	void reopen();

	bool delayWait(int ms);

protected:
	virtual void onCommand(Command& cmd);
	virtual void onIdle();
	virtual bool startup();
	virtual void cleanup();
	virtual void doStop();

protected:
	
	std::string	m_params;

	UMediaReaderPtr	m_reader;

	bool	m_isLive;
	bool	m_seekable;

	util::TimePoint	m_startPoint;
	util::TimePoint	m_lastPoint;
	int		    m_refStreamIndex;

	int64_t			m_curTime;
	AVRational	    m_scale;

	bool	m_endOfStream;
	int		m_retryDelay;
	int		m_loopCount;

	int64_t m_cutoutTime;   /// ms

	bool m_audioTsCustomed;

	comn::Event		m_eventDelay;

	bool	m_connected;

};

#endif /* UMEDIAREADERSOURCE_H_ */
